﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using JFTest.utils;
using Newtonsoft.Json;
/**
 * @ClassName: HttpClientHelper
 * @Description: 调用API接口通用类，get，post及自定义header
 * @Author: X
 * @Date: 2025/4/14 08:21
 */
namespace JFTest.Utils
{
    public enum ContentType
    {
        Json,
        FormUrlEncoded
    }

    //public class HttpResponseResult
    //{
    //    public bool IsSuccess { get; set; }
    //    public string Content { get; set; }
    //    public HttpStatusCode StatusCode { get; set; }
    //    public string ErrorMessage { get; set; }
    //}

    public class HttpClientHelper : IDisposable
    {
        private readonly HttpClient _httpClient;
        private readonly Dictionary<string, string> _headers = new Dictionary<string, string>();

        public ContentType ContentType { get; set; } = ContentType.Json;

        public TimeSpan Timeout
        {
            get { return _httpClient.Timeout; }
            set { _httpClient.Timeout = value; }
        }

        public HttpClientHelper()
        {
            _httpClient = new HttpClient();
            _httpClient.Timeout = TimeSpan.FromSeconds(100);
        }

        public void AddHeader(string key, string value)
        {
            _headers[key] = value;
        }

        public async Task<HttpResponseResult> GetAsync(string url, Dictionary<string, string> parameters = null)
        {
            try
            {
                var queryString = parameters != null ? BuildQueryString(parameters) : "";
                var requestUrl = url + queryString;

                using (var request = new HttpRequestMessage(HttpMethod.Get, requestUrl))
                {
                    AddHeadersToRequest(request);
                    using (var response = await _httpClient.SendAsync(request).ConfigureAwait(false))
                    {
                        return await ProcessResponse(response).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception ex)
            {
                return new HttpResponseResult
                {
                    IsSuccess = false,
                    ErrorMessage = ex.Message,
                    StatusCode = HttpStatusCode.InternalServerError
                };
            }
        }

        public async Task<HttpResponseResult> PostAsync(string url, object data = null)
        {
            try
            {
                using (var request = new HttpRequestMessage(HttpMethod.Post, url))
                {
                    AddHeadersToRequest(request);

                    if (data != null)
                    {
                        request.Content = CreateContent(data);
                    }

                    using (var response = await _httpClient.SendAsync(request).ConfigureAwait(false))
                    {
                        return await ProcessResponse(response).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception ex)
            {
                return new HttpResponseResult
                {
                    IsSuccess = false,
                    ErrorMessage = ex.Message,
                    StatusCode = HttpStatusCode.InternalServerError
                };
            }
        }

        private HttpContent CreateContent(object data)
        {
            switch (ContentType)
            {
                case ContentType.Json:
                    return new StringContent(
                        JsonConvert.SerializeObject(data),
                        Encoding.UTF8,
                        "application/json");

                case ContentType.FormUrlEncoded:
                    var formData = data as Dictionary<string, string>;
                    if (formData == null)
                        throw new ArgumentException(
                            "Data must be Dictionary<string, string> for FormUrlEncoded content type");

                    return new FormUrlEncodedContent(formData);

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private async Task<HttpResponseResult> ProcessResponse(HttpResponseMessage response)
        {
            var result = new HttpResponseResult
            {
                StatusCode = response.StatusCode,
                IsSuccess = response.IsSuccessStatusCode
            };

            if (response.Content != null)
            {
                result.Content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

            if (!response.IsSuccessStatusCode)
            {
                result.ErrorMessage = $"HTTP error: {(int)response.StatusCode} {response.ReasonPhrase}";
            }

            return result;
        }

        private void AddHeadersToRequest(HttpRequestMessage request)
        {
            foreach (var header in _headers)
            {
                if (!request.Headers.TryAddWithoutValidation(header.Key, header.Value))
                {
                    throw new InvalidOperationException($"Could not add header {header.Key}");
                }
            }
        }

        private string BuildQueryString(Dictionary<string, string> parameters)
        {
            var query = new StringBuilder("?");
            foreach (var param in parameters)
            {
                query.Append(Uri.EscapeDataString(param.Key));
                query.Append("=");
                query.Append(Uri.EscapeDataString(param.Value));
                query.Append("&");
            }
            if (parameters.Count > 0) query.Length--; // Remove last '&'
            return query.ToString();
        }

        public void Dispose()
        {
            _httpClient?.Dispose();
        }

        public static async Task<HttpResponseResult> GetPostJsonResult(string url, Dictionary<string, Object> parameters)
        {
            HttpClientHelper httpClient = new HttpClientHelper
            {
                ContentType = ContentType.Json
            }; 
            httpClient.AddHeader("Connection", "keep-alive");
            httpClient.AddHeader("appId", "aaa");
            httpClient.AddHeader("appKey", "bbb");
            var result = await httpClient.PostAsync(url, parameters);

            return result;
        }
    }
}
